#include "Projectile.h"
#include "MovingObject.h"
#include "Weapon.h"
#include "GameplayState.h"

Projectile::~Projectile()
{
	m_goOwner->Release();
}

void Projectile::NormalUpdate(float elapsedTime)
{
	if (m_vtVelocity.x >= 0)
		m_ptPosition.x += m_vtVelocity.x * (m_fBulletSpeed * elapsedTime);
	if (m_vtVelocity.y >= 0)
		m_ptPosition.y += m_vtVelocity.y * (m_fBulletSpeed * elapsedTime);

	if (m_vtVelocity.x < 0)
		m_ptPosition.x += (m_vtVelocity.x * (m_fBulletSpeed * elapsedTime));
	if (m_vtVelocity.y < 0)
		m_ptPosition.y += (m_vtVelocity.y * (m_fBulletSpeed * elapsedTime));

}

void Projectile::Update(float elapsedTime)
{
	if (m_ptPosition.y <= 2)
	{
		DestroyGameObjectMessage * Msg = new DestroyGameObjectMessage{ this };
		Msg->QueueMessage();
		Msg = nullptr;
		return;
	}
	m_iRange -= int(m_vtVelocity.x*elapsedTime + m_fBulletSpeed*elapsedTime);
	if (m_iRange <= 0 && m_iShotStyle != Weapon::BOOMERANG)
	{
		DestroyGameObjectMessage * Msg = new DestroyGameObjectMessage{ this };
		Msg->QueueMessage();
		Msg = nullptr;

		m_iRange = m_iRangeMax;
		return;
	}

	if (m_iRange <= 0 && m_iShotStyle == Weapon::BOOMERANG)
	{
		m_bReturning = true;

	}
	if (m_iBulletType == Weapon::MIRROR)
	{
		if (m_fRotation == -180.0f && m_bHasMirrored == false)
		{
			m_vtVelocity = -m_vtVelocity;
			m_bHasMirrored = true;
		}
	}
	if (m_iBulletType == Weapon::DAMAGE)
	{
		m_iDamage = m_iDoubleDamage;
	}

	//RAPID_FIRE=100,BEAM,PIERCING,RICOCHET,LIFE_STEAL,MIRROR,KNOCKBACK,DOT,STUN,AOE_CIRCLE,SLOW,DAMAGE
	//STRAIGHT_LINE=90,WAVE,BOOMERANG,SPREAD,ARC,HOMING
	//Handle Bullet Type Check 2nd!
	//Image is Bullet Type
	//Particle effect Bullet Type

	if (m_iShotStyle == Weapon::STRAIGHT_LINE)
	{

	}
	if (m_iShotStyle == Weapon::WAVE) //SinWave
	{
		SGD::Point target = { 0, 0 };
		if (m_vtVelocity.x >= 0)
		{
			target = { m_ptPosition.x + m_iRangeMax, m_ptPosition.y };
		}
		if (m_vtVelocity.x < 0)
		{
			target = { m_ptPosition.x - m_iRangeMax, m_ptPosition.y };
		}
		if (m_vtVelocity.y > 0)
		{
			target = { m_ptPosition.x, m_ptPosition.y + m_iRangeMax };
		}
		if (m_vtVelocity.y < 0)
		{
			target = { m_ptPosition.x, m_ptPosition.y - m_iRangeMax };
		}
		SGD::Vector dir = target - m_ptPosition; // direction
		dir.Normalize();
		SGD::Vector perp(-dir.y, dir.x); // perpendicular
		float waveAmp = .65f; // adjust if needed
		m_fTimeAlive += elapsedTime;
		float waveAngle = m_fTimeAlive * 3.14f * 1.2f; // adjust if needed
		SGD::Vector wave = perp * sin(waveAngle) * waveAmp;
		SGD::Vector vel = dir * (m_fBulletSpeed / 1.5f);
		vel.x += m_fOwnersShootingVelocity;
		m_ptPosition += (vel * elapsedTime) + wave;
		return;
	}
	if (m_iShotStyle == Weapon::BOOMERANG)
	{
		if (m_bReturning)
		{
			if (m_goOwner->GetType() == MovingObject::OBJ_PLAYER)
			{
				Player* tempplayer = (Player*)m_goOwner;
				SGD::Vector tempvec = tempplayer->GetWeaponOffset() - this->GetPosition();
				if (tempvec.x > 0)
					m_ptPosition.x += tempvec.x*elapsedTime + m_fBulletSpeed*elapsedTime;
				else
					m_ptPosition.x += (tempvec.x*elapsedTime - m_fBulletSpeed*elapsedTime);

				if (tempvec.y > 0)
					m_ptPosition.y += tempvec.y*elapsedTime + m_fBulletSpeed*elapsedTime;
				else
					m_ptPosition.y += (tempvec.y*elapsedTime - m_fBulletSpeed*elapsedTime);

				return;
			}

		}
	}
	if (m_iShotStyle == Weapon::SPREAD) //Tri Shot
	{
#if 0
		SGD::Vector orientation = m_goOwner->GetAiming();

		if (m_fRotation == 45)
		{
			orientation.Rotate(-SGD::PI / 4);
		}
		if(m_fRotation == -45)
		{
			orientation.Rotate(SGD::PI/4);
		}

		m_vtVelocity.x *= (orientation.x*2);
		m_vtVelocity.y *= (orientation.y*2);
		m_ptPosition += m_vtVelocity *elapsedTime;

#endif
#if 1
		SGD::Vector veloc = m_vtVelocity;
		if (m_fRotation == 45)
		{
			if (veloc.x > 0 && veloc.y == 0)
			{
				veloc.x =  200;
				veloc.y = -200;
			}
			else if (veloc.x > 0 && veloc.y < 0)
			{
				veloc.x = 0;
				veloc.y = -200;
			}
			else if (veloc.x < 0 && veloc.y < 0)
			{
				veloc.x = 0;
				veloc.y = -200;
			}
			else if (veloc.x > 0 && veloc.y > 0)
			{
				veloc.x = 200;
				veloc.y = 0;
			}
			else if (veloc.x < 0 && veloc.y > 0)
			{
				veloc.x = -200;
				veloc.y = 0;
			}
			else if (veloc.x < 0 && veloc.y == 0)
			{
				veloc.x = -200;
				veloc.y = -200;
			}
			else if (veloc.x == 0)
			{
				if (veloc.y > 0)
				{
					veloc.y = 200;
					veloc.x = -200;
				}
				if (veloc.y < 0)
				{
					veloc.y = -200;
					veloc.x = -200;
				}

			}
		}
		if (m_fRotation == -45)
		{
			if (veloc.x > 0 && veloc.y == 0)
			{
				veloc.x = 200;
				veloc.y = 200;
			}
			else if (veloc.x > 0 && veloc.y < 0)
			{
				veloc.x = 200;
				veloc.y = 0;
			}
			else if (veloc.x < 0 && veloc.y < 0)
			{
				veloc.x = -200;
				veloc.y = 0;
			}
			else if (veloc.x > 0 && veloc.y > 0)
			{
				veloc.x = 0;
				veloc.y = 200;
			}
			else if (veloc.x < 0 && veloc.y > 0)
			{
				veloc.x = 0;
				veloc.y = -200;
			}
			else if (veloc.x < 0 && veloc.y == 0)
			{
				veloc.x = -200;
				veloc.y = 200;
			}
			else if (veloc.x == 0)
			{
				if (veloc.y > 0)
				{
					veloc.x = 200;
					veloc.y = 200;
				}
				if (veloc.y < 0)
				{
					veloc.y = -200;
					veloc.x = 200;
				}

			}
		}
		if (m_fRotation == 0)
		{
			NormalUpdate(elapsedTime);
			return;
		}

		m_ptPosition += veloc*elapsedTime;
#endif
		return;
	}
	if (m_iShotStyle == Weapon::ARC)
	{
		if (!gravityOn)
		{
			gravityOn = true;
			if (m_vtVelocity.y < 0 && m_vtVelocity.x == 0)
				m_vtVelocity.y = -.5f;
			if (m_vtVelocity.y < 0 && m_vtVelocity.x != 0)
				m_vtVelocity.y = -.3f;
		}
		m_vtVelocity += (gravity*.0005f)*elapsedTime;
		NormalUpdate(elapsedTime);
		return;
	}
	if (m_iShotStyle == Weapon::HOMING)
	{
		if (m_goOwner->GetType() == MovingObject::OBJ_PLAYER)
		{
			if (m_pTarget == nullptr)
			{
				Player* tempplayer = (Player*)m_goOwner;
				MovingObject* closestenemy = (MovingObject*)(tempplayer->GetClosestEnemy());
				if (closestenemy != nullptr)
					m_pTarget = closestenemy;
			}
			if (m_pTarget != nullptr && m_goOwner != nullptr && (m_pTarget->GetPosition().y - 400) > m_goOwner->GetPosition().y)
				m_pTarget = nullptr;
			if (m_pTarget != nullptr)
			{
				SGD::Point imapointbitch = m_pTarget->GetPosition();
				imapointbitch.y -= m_pTarget->GetRect().ComputeHeight() / 2;
				SGD::Vector targvec = imapointbitch - (m_ptPosition);
				targvec.Normalize();
				targvec *= 1;
				m_vtVelocity.x = targvec.x;
				m_vtVelocity.y = targvec.y;
			}
		}
	}
	//****************************************************************


	NormalUpdate(elapsedTime);
	myEmitter->Update(elapsedTime);
}

void Projectile::Render(void)
{
	SGD::GraphicsManager * pGraphics = SGD::GraphicsManager::GetInstance();

	m_hImage = GameplayState::GetInstance()->GetBulletImage();
	if (m_iBulletType == Weapon::RAPID_FIRE)
	{
		MovingObject * temp = (MovingObject*)m_goOwner;
		pGraphics->DrawTextureSection(m_hImage, SGD::Point(GetRect().left - Game::GetInstance()->GetCameraPos().x,
			GetRect().top - Game::GetInstance()->GetCameraPos().y), SGD::Rectangle(SGD::Point(32, 667), SGD::Point(63, 696)));
	}
	if (m_iBulletType == Weapon::BEAM)
	{
		SGD::Point bulletposition;
		bulletposition.x = this->GetPosition().x - Game::GetInstance()->GetCameraPos().x;
		bulletposition.y = this->GetPosition().y - Game::GetInstance()->GetCameraPos().y;
		MovingObject * temp = (MovingObject*)m_goOwner;
		SGD::Point Playerposition;
		Playerposition.x = temp->GetWeaponOffset().x - Game::GetInstance()->GetCameraPos().x;
		Playerposition.y = temp->GetWeaponOffset().y - Game::GetInstance()->GetCameraPos().y;
		pGraphics->DrawLine(bulletposition, Playerposition, { 255, 0, 105 }, 5);
	}
	if (m_iBulletType == Weapon::PIERCING)
	{
		MovingObject * temp = (MovingObject*)m_goOwner;
		pGraphics->DrawTextureSection(m_hImage, SGD::Point(GetRect().left - Game::GetInstance()->GetCameraPos().x,
			GetRect().top - Game::GetInstance()->GetCameraPos().y), SGD::Rectangle(SGD::Point(310, 502), SGD::Point(337, 527)));
	}
	if (m_iBulletType == Weapon::RICOCHET)
	{
		MovingObject * temp = (MovingObject*)m_goOwner;
		pGraphics->DrawTextureSection(m_hImage, SGD::Point(GetRect().left - Game::GetInstance()->GetCameraPos().x,
			GetRect().top - Game::GetInstance()->GetCameraPos().y), SGD::Rectangle(SGD::Point(194, 504), SGD::Point(217, 526)));
	}
	if (m_iBulletType == Weapon::LIFE_STEAL)
	{
		MovingObject * temp = (MovingObject*)m_goOwner;
		pGraphics->DrawTextureSection(m_hImage, SGD::Point(GetRect().left - Game::GetInstance()->GetCameraPos().x,
			GetRect().top - Game::GetInstance()->GetCameraPos().y), SGD::Rectangle(SGD::Point(157, 169), SGD::Point(183, 197)));
	}
	if (m_iBulletType == Weapon::MIRROR)
	{
		MovingObject * temp = (MovingObject*)m_goOwner;
		pGraphics->DrawTextureSection(m_hImage, SGD::Point(GetRect().left - Game::GetInstance()->GetCameraPos().x,
			GetRect().top - Game::GetInstance()->GetCameraPos().y), SGD::Rectangle(SGD::Point(219, 666), SGD::Point(244, 689)));
	}
	if (m_iBulletType == Weapon::KNOCKBACK)
	{
		MovingObject * temp = (MovingObject*)m_goOwner;
		pGraphics->DrawTextureSection(m_hImage, SGD::Point(GetRect().left - Game::GetInstance()->GetCameraPos().x,
			GetRect().top - Game::GetInstance()->GetCameraPos().y), SGD::Rectangle(SGD::Point(151, 98), SGD::Point(163, 110)));
	}
	if (m_iBulletType == Weapon::DOT)
	{
		MovingObject * temp = (MovingObject*)m_goOwner;
		pGraphics->DrawTextureSection(m_hImage, SGD::Point(GetRect().left - Game::GetInstance()->GetCameraPos().x,
			GetRect().top - Game::GetInstance()->GetCameraPos().y), SGD::Rectangle(SGD::Point(109, 19), SGD::Point(130, 38)));
	}
	if (m_iBulletType == Weapon::STUN)
	{
		MovingObject * temp = (MovingObject*)m_goOwner;
		pGraphics->DrawTextureSection(m_hImage, SGD::Point(GetRect().left - Game::GetInstance()->GetCameraPos().x,
			GetRect().top - Game::GetInstance()->GetCameraPos().y), SGD::Rectangle(SGD::Point(19, 376), SGD::Point(54, 410)));
	}
	if (m_iBulletType == Weapon::AOE_CIRCLE)
	{
		MovingObject * temp = (MovingObject*)m_goOwner;
		if (!exploded)
			pGraphics->DrawTextureSection(m_hImage, SGD::Point(GetRect().left - Game::GetInstance()->GetCameraPos().x,
			GetRect().top - Game::GetInstance()->GetCameraPos().y), SGD::Rectangle(SGD::Point(17, 20), SGD::Point(36, 39)));
		else if (exploded)
		{
			pGraphics->DrawTextureSection(m_hImage, SGD::Point(GetRect().left - Game::GetInstance()->GetCameraPos().x,
				GetRect().top - Game::GetInstance()->GetCameraPos().y), SGD::Rectangle(SGD::Point(17, 20), SGD::Point(36, 39)), {}, {}, {}, { 5.0f, 5.0f });

				DestroyGameObjectMessage * Msg = new DestroyGameObjectMessage{ this };
				Msg->QueueMessage();
				Msg = nullptr;
		}
	}
	if (m_iBulletType == Weapon::SLOW)
	{
		MovingObject * temp = (MovingObject*)m_goOwner;
		pGraphics->DrawTextureSection(m_hImage, SGD::Point(GetRect().left - Game::GetInstance()->GetCameraPos().x,
			GetRect().top - Game::GetInstance()->GetCameraPos().y), SGD::Rectangle(SGD::Point(19, 172), SGD::Point(42, 194)));
	}
	if (m_iBulletType == Weapon::DAMAGE)
	{
		MovingObject * temp = (MovingObject*)m_goOwner;
		pGraphics->DrawTextureSection(m_hImage, SGD::Point(GetRect().left - Game::GetInstance()->GetCameraPos().x,
			GetRect().top - Game::GetInstance()->GetCameraPos().y), SGD::Rectangle(SGD::Point(168, 261), SGD::Point(202, 294)));
	}

	//Render projectiles emitter
	if (myEmitter)
		myEmitter->Render();
}

void Projectile::HandleCollision(GameObject* pOther)
{
	if (!dynamic_cast<StaticObject *>(pOther))
	{


		if (m_iShotStyle == Weapon::BOOMERANG)
		{
			if (pOther->GetType() == MovingObject::OBJ_PLAYER && m_bReturning == true)
			{
				DestroyGameObjectMessage * Msg = new DestroyGameObjectMessage{ this };
				Msg->QueueMessage();
				Msg = nullptr;
			}
			if (pOther->GetType() != MovingObject::OBJ_PLAYER)
			{
				m_bReturning = true;
			}
		}

		MovingObject *disting = dynamic_cast<MovingObject *>(pOther);
		if (disting == m_goOwner)
			return;

		if (disting != GameplayState::GetInstance()->GetPlayer())
		{

		}

		if (m_iBulletType == Weapon::RICOCHET)
		{
			//DO ricochet shit
			m_vtVelocity = -m_vtVelocity;
			if (m_goOwner->GetType() != OBJ_PLAYER && pOther->GetType() != OBJ_PLAYER)//prevent the bullet from reflecting off of anything that isnt the player
			{
				DestroyGameObjectMessage * Msg = new DestroyGameObjectMessage{ this };
				Msg->QueueMessage();
				Msg = nullptr;
			}
		}
		if (m_iBulletType == Weapon::DOT)
		{
			//Send Dot Event
			SGD::Event* dot = new SGD::Event("DOT", (void*)pOther, nullptr);
			dot->SendEventNow();
			delete dot;
			dot = nullptr;
		}
		if (m_iBulletType == Weapon::SLOW)
		{
			//Send Slow Event
			SGD::Event* slow = new SGD::Event("SLOW", (void*)pOther, nullptr);
			slow->SendEventNow();
			delete slow;
			slow = nullptr;
		}
		if (m_iBulletType == Weapon::STUN)
		{
			//Send Stun Event
			SGD::Event* stun = new SGD::Event("STUN", (void*)pOther, nullptr);
			stun->SendEventNow();
			delete stun;
			stun = nullptr;
		}
		if (m_iBulletType == Weapon::KNOCKBACK)
		{
			//Send KnockBack Event
			SGD::Event* knockback = new SGD::Event("KNOCKBACK", (void*)pOther, nullptr);
			knockback->SendEventNow();
			delete knockback;
			knockback = nullptr;
		}
		if (m_iBulletType == Weapon::LIFE_STEAL)
		{
			//Send LifeSteal Event.
			SGD::Event* lifeSteal = new SGD::Event("LIFESTEAL", (void*)&m_iDamage, m_goOwner);
			lifeSteal->SendEventNow();
			delete lifeSteal;
			lifeSteal = nullptr;
		}
		if (m_iBulletType == Weapon::AOE_CIRCLE)
		{
			if (m_goOwner != pOther)
			{
				m_szSize *= 5;
				exploded = true;
				m_vtVelocity = { 0, 0 };

			}
		}
		if (m_iBulletType != Weapon::PIERCING && m_iBulletType != Weapon::RICOCHET && m_iBulletType != Weapon::BOOMERANG && m_iBulletType != Weapon::AOE_CIRCLE)
		{
			DestroyGameObjectMessage * Msg = new DestroyGameObjectMessage{ this };
			Msg->QueueMessage();
			Msg = nullptr;
		}
	}
}
